﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using log4net;
using BidFunLib.DAO;
using BidFunLib.Entity;

namespace BidFunLib.Services
{
    public class BidLoggerManager
    {
        private static readonly ILog log = LogManager.GetLogger(typeof(BidLoggerManager));

        /// <summary>
        /// Singleton instance
        /// </summary>
        private static BidLoggerManager instance;

        /// <summary>
        /// Retreive singleton of this class
        /// </summary>
        public static BidLoggerManager Instance
        {
            get
            {
                if (instance == null)
                {
                    instance = new BidLoggerManager();
                }
                return BidLoggerManager.instance;
            }
            set
            {
                BidLoggerManager.instance = value;
            }
        }

        /// <summary>
        /// The dao of this manager
        /// </summary>
        private BidLoggerDAO dao = new BidLoggerDAO();

        
        /// <summary>
        /// 
        /// </summary>
        private BidLoggerManager()
        {
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="bidLogger"></param>
        /// <returns></returns>
        public BidLogger saveOrUpdate(BidLogger bidLogger)
        {
            return dao.saveOrUpdateBidLogger(bidLogger);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="idBidSale"></param>
        /// <param name="orderString"></param>
        /// <returns></returns>
        public List<BidLogger> getLoggersByIdBidSale(BidSale bidSale)
        {
            return new List<BidLogger>(dao.getAllBidLoggerForSpecificIdBidSale(bidSale.IdBidSale));
        }


        /// <summary>
        /// 
        /// </summary>
        /// <param name="idBidSale"></param>
        /// <returns></returns>
        public Dictionary<Int32, StatsBidUserByBidSale> getMapUserLoggersForOneSale(BidSale bidSale)
        {
            Dictionary<Int32, StatsBidUserByBidSale> mapStatsBidUserByBidSale = new Dictionary<Int32, StatsBidUserByBidSale>();

            List<BidLogger> saleLoggersList = getLoggersByIdBidSale(bidSale);

            foreach (BidLogger bl  in saleLoggersList)
            {
                StatsBidUserByBidSale statsBidUserByBidSale = null;

                // retreive the StatsBidUserByBidSale corresponding to the idUser
                if (mapStatsBidUserByBidSale.ContainsKey(bl.IdBidUser)) {
                    statsBidUserByBidSale = mapStatsBidUserByBidSale[bl.IdBidUser];
                }
                else {
                    log.Info("StatsBidUserByBidSale doesn't exist in local list => new one created.");
                    // we create a new stat element as it was unknown in map
                    statsBidUserByBidSale = new StatsBidUserByBidSale();
                    statsBidUserByBidSale.IdStatsBidUserByBidSale = -1;
                    statsBidUserByBidSale.IdBidSale = bidSale.IdBidSale;
                    statsBidUserByBidSale.IdBidObject= bidSale.IdBidObject;
                    statsBidUserByBidSale.IdBidUser = bl.IdBidUser;

                    // store it in the map
                    mapStatsBidUserByBidSale.Add(bl.IdBidUser, statsBidUserByBidSale);
                }

                // common part
                statsBidUserByBidSale.NbBids++;

                if (bl.BidOperatorType.BidOperatorTypeAsEnum == BidFunLib.Services.BidOperatorTypeManager.BID_OPERATOR_TYPE.AUTOMATIC) 
                {
                    statsBidUserByBidSale.NbBidsByBot++;
                }
                else if (bl.BidOperatorType.BidOperatorTypeAsEnum == BidFunLib.Services.BidOperatorTypeManager.BID_OPERATOR_TYPE.MANUAL)
                {
                    statsBidUserByBidSale.NbBidsManual++;
                }

                if (bl.Winner) 
                {
                    statsBidUserByBidSale.Winner = true;
                }

                statsBidUserByBidSale.RealPricePaidByUser = 0.75 * statsBidUserByBidSale.NbBids + bl.AmountAsDouble;

                Double realPrice = bidSale.BidObject.RealPriceAsDouble;

                if (realPrice != 0)
                {
                    statsBidUserByBidSale.PsychologicRatio =100 *(statsBidUserByBidSale.RealPricePaidByUser / realPrice);
                }

                log.Debug("StatsBidUserByBidSale = " + statsBidUserByBidSale);
            }

            return mapStatsBidUserByBidSale;
        }

    
    }
}
